#ifndef BOUNDINGBOX_H
#define BOUNDINGBOX_H

#include "Model.h"

#ifdef __APPLE__
    #include <OpenGL/OpenGL.h>
    #include <GLUT/glut.h>
#else
    #include <GL/glut.h>
#endif

struct BoundingBox
{
public:
    BoundingBox() 
	{
		translation.SetPoints(0, 0, 0);
	}
    
    void SetCentre(Point p)
    {
		direction.SetPoints(0, 0, 1);
        centre = p;
		target = p + direction;
		UpdateBoundary();
    }

	void MoveForward(Point dP)
	{
		translation = translation + dP;
	}

	Point GetCentre()
	{
		return centre;
	}

	Point GetTarget()
	{
		return target;
	}

	Point GetDirection()
	{
		return direction;
	}

	void UpdateBoundary()
	{
		Point p;
		boxVertices.clear();
		lineVertices.clear();
        
        // box vertices start
        p.SetPoints(centre.x + width/2, centre.y + height/2, centre.z + depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x + width/2, centre.y - height/2, centre.z + depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y - height/2, centre.z + depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y + height/2, centre.z + depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x + width/2, centre.y + height/2, centre.z - depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x + width/2, centre.y - height/2, centre.z - depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y - height/2, centre.z - depth/2);
        boxVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y + height/2, centre.z - depth/2);
        boxVertices.push_back(p);
        // box vertices end
        
        // line vertices start
        p.SetPoints(centre.x + width/2, centre.y + height/2, centre.z + depth/2);
        lineVertices.push_back(p);
        p.SetPoints(centre.x + width/2, centre.y + height/2, centre.z - depth/2);
        lineVertices.push_back(p);
        
        p.SetPoints(centre.x + width/2, centre.y - height/2, centre.z + depth/2);
        lineVertices.push_back(p);
        p.SetPoints(centre.x + width/2, centre.y - height/2, centre.z - depth/2);
        lineVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y - height/2, centre.z + depth/2);
        lineVertices.push_back(p);
        p.SetPoints(centre.x - width/2, centre.y - height/2, centre.z - depth/2);
        lineVertices.push_back(p);
        
        p.SetPoints(centre.x - width/2, centre.y + height/2, centre.z + depth/2);
        lineVertices.push_back(p);
        p.SetPoints(centre.x - width/2, centre.y + height/2, centre.z - depth/2);
        lineVertices.push_back(p);
        
        // line vertices end
	}
    
    void SetBoundary(float _width, float _height, float _depth)
    {
        width = _width;
		height = _height;
		depth = _depth;

		UpdateBoundary();
    }
    
    void DrawBoundingBox()
    {
		glDisable(GL_LIGHTING);
		glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );


		glPushMatrix();
			glTranslatef(translation.x, translation.y, translation.z);
			glBegin(GL_LINE_LOOP);
        
			for (unsigned int i = 0; i < boxVertices.size()/2; i++)
			{
				glVertex3f(boxVertices[i].x, boxVertices[i].y, boxVertices[i].z);
			}

			glEnd();

			glBegin(GL_LINE_LOOP);

			for (unsigned int i = boxVertices.size()/2; i < boxVertices.size(); i++)
			{
				glVertex3f(boxVertices[i].x, boxVertices[i].y, boxVertices[i].z);
			}
        
			glEnd();
        
			for (unsigned int i = 0; i < lineVertices.size(); i+=2)
			{
				glBegin(GL_LINE_LOOP);
				glVertex3f(lineVertices[i].x, lineVertices[i].y, lineVertices[i].z);
				glVertex3f(lineVertices[i+1].x, lineVertices[i+1].y, lineVertices[i+1].z);
				glEnd();
			}

		glPopMatrix();

		glPushMatrix();
			glColor3f(0, 0, 1);
			glTranslatef(centre.x, centre.y, centre.z);
			glTranslatef(translation.x, translation.y, translation.z);
			glutSolidCube(0.1);
		glPopMatrix();

		glPushMatrix();

			glColor3f(0, 1, 0);

			glTranslatef(target.x, target.y, target.z);
			glTranslatef(translation.x, translation.y, translation.z);
			glutSolidCube(0.1);

			glColor3f(1, 1, 1);

		glPopMatrix();

		glPushMatrix();
			glTranslatef(translation.x, translation.y, translation.z);
			glBegin(GL_LINES);
				glVertex3f(centre.x, centre.y, centre.z);
				glVertex3f(target.x, target.y, target.z);
			glEnd();
		glPopMatrix();
    }
    
private:
    vector<Point> boxVertices;
    vector<Point> lineVertices;
    Point centre, target, direction, translation;
	float width, height, depth;
    
};

#endif